package whf.framework.web.query;

import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import whf.framework.entity.PropertyTypeEnum;
import whf.framework.meta.MetaManager;
import whf.framework.meta.entity.IMeta;
import whf.framework.meta.entity.IProperty;
import whf.framework.security.UserContext;
import whf.framework.util.BeanUtils;
import whf.framework.util.ParamUtils;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;
import whf.framework.web.Constants;
import whf.framework.web.WebContextHolder;

/**
 * @author wanghaifeng
 *
 */
@SuppressWarnings("unchecked")
public class QueryBuilder {
	
	public static List<Field> buildQueryFields(HttpServletRequest request) throws Exception{
		boolean query = ParamUtils.getBooleanParameter(request, Constants.QUERY_FORM_TAG, false);
		if(query){
			String queryId = null;
			String boClassName = request.getParameter(Constants.BO_CLASS_NAME);
			Class boClass = Utils.getClassByClassName(boClassName);
			String metaType = ParamUtils.getParameter(request, boClassName + Constants.META_TYPE);
			IMeta meta = null;
			if("view".equalsIgnoreCase(metaType)){
				String viewCode = request.getParameter(boClassName + Constants.META_VIEW);
				queryId = "VIEW:" + viewCode;
				meta = MetaManager.getDefaultInstance().findView(viewCode);
			} else {
				meta = MetaManager.getDefaultInstance().findByEntityClass(boClassName);
				queryId = "OBJECT:" + meta.getId();
			}
			//
			String namePrefix = ParamUtils.getNamePrefix(request, boClass);
			Object objectInstance = Utils.constructBean(boClass);
			Set<IProperty> properties = meta.getProperties();
			List<Field> fields = Utils.newArrayList();
			for(IProperty property: properties){
				PropertyTypeEnum type = BeanUtils.getPropertyType(objectInstance, property);
				//
				String parameterName = namePrefix + property.getName(); 
				String[] values = null;
				if(type == PropertyTypeEnum.ENTITY) {
					values = request.getParameterValues(parameterName + Constants.BOID_SUFFIX);
				} else if(type == PropertyTypeEnum.DATETIME) {
					String start = request.getParameter(parameterName + "_1");
					String end = request.getParameter(parameterName + "_2");
					if(!StringUtils.isEmpty(start) || !StringUtils.isEmpty(end)) {
						values = new String[]{start, end};
					}
				} else if(type == PropertyTypeEnum.DOUBLE || type == PropertyTypeEnum.FLOAT || 
						type == PropertyTypeEnum.LONG || type == PropertyTypeEnum.INTEGER ) {
					String start = request.getParameter(parameterName + "_1");
					String end = request.getParameter(parameterName + "_2");
					if(StringUtils.isNumeric(start) || StringUtils.isNumeric(end)) {
						values = new String[]{start, end};
					}
				} else {
					values = request.getParameterValues(parameterName);
				}
				if(values == null || values.length == 0) continue;
				//
				fields.add(FieldFactory.getField(property.getName(), values, type));
			}
			UserContext userContext = WebContextHolder.getWebContext(request).getUserContext();
			userContext.setQueryFieldValues(queryId, fields);
			return fields;
		}
		return null;
	}
	
	public static String buildQueryString(HttpServletRequest request) throws Exception{
		List<Field> fields = buildQueryFields(request);
		if(fields == null) return null;
		//
		StringBuilder hql = new StringBuilder();
		for(Field field: fields){
			String t = field.toHQLString();
			if(!StringUtils.isEmpty(t)){
				if(hql.length() > 0) hql.append(" and ");
				hql.append(t);
			}
		}
		return hql.toString();
	}
}
